require "Battle/Manager/SpineEffectManager"
require "Battle/Entity/EffectFunctions"
require "Battle/Manager/EffectManager"


ParticleSystemEffect = {}
local ParticleSystemEffect = ParticleSystemEffect
local mt = {__index = ParticleSystemEffect}


--用于跟随的 Particle System 特效
function ParticleSystemEffect:new(param)

    local object ={};

    object.name = param.effectRes;
    local nameSp = string.split(object.name,"/");
    object.subName = nameSp[#nameSp];
    object.depth = param.depth;
    object.pos = param.pos;
    object.offset = param.offset;

    --object.duration = param.duration;
    --object.loop = param.loop;

    object.flip = param.flip ;

    object.follow = param.follow;
    object.followInfo = param.followInfo;

    object.color = param.color;
    object.delayEndTime = param.delayEndTime;

    object.fighterId = param.fighterId;

    --internal vars
    object.renderOrder = -100;
    object.ending = false;
    object.handle = nil;
    object.loaded = false;
    object.particleSystems = {};

    ParticleSystemEffectParam.Put(param);

    setmetatable(object, mt);
    return object;

end

function ParticleSystemEffect:start()

    --logMy('PaticleSystemEffect:start', self.name);

    self.ending = false;

    self.rotatedOffset = EffectFunctions.rotateOffset(self.offset, self.flip, self.rotatedOffset);

    if self.followInfo and self.followInfo.offset then
        self.followInfo.rotatedOffset = EffectFunctions.rotateOffset(self.followInfo.offset, self.flip, self.followInfo.rotatedOffset);
    end

    if not self.handle then
		self.handle = UpdateBeat:Add(self.update, self);
		--self.handle = LateUpdateBeat:Add(self.update, self);
    end

	local effGo =  EffectManager.getEffect(self.subName)
	local effName = self.name;
	--self.ending = false;
    self.loaded = false;

    if effGo == nil then
        resMgr:LoadModelPrefab("Fx/"..effName,function(obj)

            --如果在异步载入的过程中，由于buff结束已经被删掉了
            if self.ending then
                return;
            end

            self.effGo = newObject(obj);
            Util.Lua_SetLocalScaleXYZ(self.effGo.transform,1,1,1)
            Util.Lua_SetLocalRotationXYZ(self.effGo.transform,40,0,0)

            self:init();
            self:initPosition();
            self.loaded = true;

            self:play();

        end);
    else
		self.effGo = effGo
        Util.Lua_SetLocalScaleXYZ(self.effGo.transform,1,1,1)
        Util.Lua_SetLocalRotationXYZ(self.effGo.transform,40,0,0)

        self:init();
        self:initPosition();
        self.loaded = true;

        self:play();
    end
end


function ParticleSystemEffect:initPosition()

    if self.follow then
        self:updateFollowPosition();
    else
        self.position = self.pos + self.rotatedOffset;
        self.effGo.transform.position = self.position;
    end

    --enable
    self.effGo:SetActive(true);
end

function ParticleSystemEffect:init()

    --self.particleSystems = self.effGo:GetComponentsInChildren(TParticleSystem);
    local ps = self.effGo:GetComponentInChildren(TParticleSystem);
    table.clear(self.particleSystems);
    if self.particleSystems == nil then 
        self.particleSystems = {};
    end
    self.particleSystems[1] = ps;
    --logMy('self.particleSystems', #self.particleSystems, self.particleSystems);

    self:initColor();
    self:updateRenderOrder();

    --disable
    self.effGo:SetActive(false);
end

function ParticleSystemEffect:initColor()

    if self.color then
        for k, v in pairs(self.particleSystems) do
            -- v.main.startColor = UnityEngine.ParticleSystem.MinMaxGradient(self.color);--self.color;
            Util.Lua_SetParticleMainStartColor(v,self.color.r,self.color.g,self.color.b,self.color.a)
        end
    end
end

function ParticleSystemEffect:updateRenderOrder()

    local newRenderOrder = self.depth;
    if FightManager.cutInState and self.fighterId == FightManager.cutInFighterId and self.depth ~= Config.SortingDefault.FullScreen then
        newRenderOrder = self.depth + Config.SortingDefault.FullScreen;
    end

    if newRenderOrder ~= self.renderOrder then

        for k, v in pairs(self.particleSystems) do
            self:setSortingOrder(v, newRenderOrder);
        end

        self.renderOrder = newRenderOrder;
    end
end

function ParticleSystemEffect:setSortingOrder(ps, d)
    --renderer not found...
    --ps.renderer.sortingOrder = d;

    local renderer = ps:GetComponent(TParticleSystemRenderer);
    if renderer then
        renderer.sortingOrder = d;
    end
end

function ParticleSystemEffect:play()
    self.pauseState = false;

    for k, v in pairs(self.particleSystems) do
        if v then
            v:Play();
        end
    end
end

function ParticleSystemEffect:pause()
    self.pauseState = true;

    for k, v in pairs(self.particleSystems) do
        if v then
            v:Pause();
        end
    end
end


function ParticleSystemEffect:stopDelay()

    local delay = self.delayEndTime;
    if delay > 0.01 then -- > 0
        local time1 = Time.time;
        --logMy('ParticleSystemEffect:stopDelay wait', time1);
        -- Util.WaitForSeconds(function ()
        --     --logMy('ParticleSystemEffect:stopDelay do', Time.time - time1, delay);
        --     self:stop();
        -- end, delay);

        utimer.delayCall(function()
            self:stop()
        end, delay * 1000 )
    else
        self:stop();
    end
end

function ParticleSystemEffect:stop()
    if self.ending then
        return;
    end
    self.ending = true

    if self.handle then
        UpdateBeat:Remove(self.update, self);
        self.handle = nil;
    end
    if self.particleSystems then
        for k, v in pairs(self.particleSystems) do
            if v then
                v:Stop();
            end
        end
    end
    self.particleSystems = nil;

    if self.effGo ~= nil then
        EffectManager.releaseEffect(self.effGo, self.name)
        self.effGo = nil;
    end
    self.loaded = false
 end

function ParticleSystemEffect:update()
    if self.ending or self.effGo == nil or (not self.loaded) then
        return
    end

    if self.pauseState ~= nil and self.pauseState then
        return;
    end

    self:updateRenderOrder();

    --if  self.duration == nil then
    --    return;
    --end

    --if not self.loop then
    --    self.duration = self.duration - Time.deltaTime;
    --    if self.duration <= 0 then
    --        self:stop();
    --        return;
    --    end
    --end

    self:updateFollowPosition();

end

function ParticleSystemEffect:updateFollowPosition()

    if self.follow and not HelperFunc.IsNull(self.effGo)  and self.effGo.transform then
        EffectFunctions.calcFollowPositionV2(self.followInfo);
        if self.followInfo.position then
            local pos = self.followInfo.position;
            Util.Lua_SetPositionXYZ(self.effGo.transform,pos.x,pos.y,pos.z);
        end
    end

end

